package com.example.common.widget

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import com.example.common.R
import com.example.common.tools.LogUtils

class DownProgress : View {

    /**
     * 画笔
     */
    private var mPaint: Paint? = null

    /**
     * 默认进度值
     */
    private var mProgress = 0

    /**
     * 最大值
     */
    private var max = 100

    /**
     * 是否为温度
     */
    private var isTemperature = false

    /**
     * 进度边距
     */
    private val mProgressPadding = dp2px(5)

    /**
     * 控件高度
     */
    private var mHeight = 0

    /**
     * 字体大小
     */
    internal var mTextSize = 18f

    /**
     * 是否显示文字
     */
    internal var showText = true

    /**
     * 进度条是否为圆角
     */
    internal var isRadius = false

    /**
     * 左边进度条颜色
     */
    internal var mProgressColor = Color.RED

    /**
     * 文字颜色
     */
    internal var mTextColor = Color.RED

    /**
     * 右边进度条颜色
     */
    internal var mBackgroundColor = Color.RED

    /**
     * 左边进度条高度
     */
    internal var mProgressHeight = dp2px(10)

    /**
     * 右边进度条高度
     */
    internal var mBackgroundHeight = dp2px(10)

    /**
     * 是否为渐变
     */
    internal var isGradient = false

    /**
     * 渐变色的结束色
     * @param context
     */
    internal var endColor = Color.YELLOW


    constructor(context: Context) : super(context, null)

    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init(attrs)
    }


    /**
     * 初始化
     */
    private fun init(attrs: AttributeSet) {
        mPaint = Paint()
        mPaint!!.isAntiAlias = true//抗锯齿
        mPaint!!.color = Color.RED//画笔颜色
        val ta = context.obtainStyledAttributes(attrs, R.styleable.DownProgress)
        //获取参数
        mProgressColor = ta.getColor(R.styleable.DownProgress_progress_color, mProgressColor)
        mTextColor = ta.getColor(R.styleable.DownProgress_text_color, mTextColor)
        mBackgroundColor = ta.getColor(R.styleable.DownProgress_background_color, mBackgroundColor)
        //左边渐变进度条
        mProgressHeight =
            ta.getDimension(R.styleable.DownProgress_progress_height, mProgressHeight.toFloat())
                .toInt()
        //右边灰色进度条
        mBackgroundHeight =
            ta.getDimension(R.styleable.DownProgress_background_height, mBackgroundHeight.toFloat())
                .toInt()
        mTextSize = ta.getDimension(R.styleable.DownProgress_text_size, mTextSize)
        mProgress = ta.getInt(R.styleable.DownProgress_progress, mProgress)
        max = ta.getInt(R.styleable.DownProgress_maxValue, max)
        isTemperature = ta.getBoolean(R.styleable.DownProgress_isTemperature, isTemperature)
        showText = ta.getBoolean(R.styleable.DownProgress_showText, showText)
        isRadius = ta.getBoolean(R.styleable.DownProgress_progress_radius, isRadius)
        isGradient = ta.getBoolean(R.styleable.DownProgress_isGradient, isGradient)
        endColor = ta.getColor(R.styleable.DownProgress_end_color, endColor)
        ta.recycle()
        mPaint!!.textSize = mTextSize//设定文字大小，后续好测量文字高度
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        val widthMode = View.MeasureSpec.getMode(widthMeasureSpec)//得到测量模式
        val widthVal = View.MeasureSpec.getSize(widthMeasureSpec)//默认用户需要给出明确值，所以不判断模式
        val height = measureHeight(heightMeasureSpec)
        setMeasuredDimension(widthVal, height)//设置了测量值后，可以获取测量值。
        //mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //获取高度
        mHeight = measuredHeight
        //设置文本格式
        var str = "$mProgress%"
        //设置文本为温度
        if (isTemperature) str = "$mProgress℃"
        //获取文本宽度
        var textWidth = mPaint!!.measureText(str)
        //不显示文字，文本宽度为0
        if (!showText) textWidth = 0f

        //控件宽度-文本宽度-padding=进度条总宽度，即已加载部分长度
        val width =
            measuredWidth.toFloat() - textWidth - paddingLeft.toFloat() - paddingRight.toFloat() - (mProgressPadding * 2).toFloat()
        //当前进度应该绘制的结束位置
        val currentProgress = paddingLeft + width * mProgress / max
        //设置进度条的颜色和高度
        mPaint!!.color = mProgressColor
        mPaint!!.strokeWidth = mProgressHeight.toFloat()
        //直线为圆角时的偏差值
        var r = 0
        if (isRadius) {
            //设置直线末端为圆角
            mPaint!!.strokeCap = Paint.Cap.ROUND
            r = if (mProgress < 1) {
                0
            } else {
                //圆角的宽度
                mProgressHeight / 2
            }
        }

        //直线是否为渐变色
        if (isGradient) {
            //设置线性渐变，开始位置和结束位置于进度条相同
            val shader = LinearGradient(
                paddingLeft.toFloat(),
                (mHeight / 2).toFloat(),
                currentProgress,
                (mHeight / 2).toFloat(),
                mProgressColor,
                endColor,
                Shader.TileMode.REPEAT
            )
            mPaint!!.shader = shader
        }
        //画进度条，当存在圆角时，需要考虑圆角，在画直线的时候，圆角的长度是不考虑进去的，所以在开始坐标要加上r,结束坐标要减去r

        canvas!!.drawLine(
            (paddingLeft + r).toFloat(),
            (mHeight / 2).toFloat(),
            currentProgress - r,
            (mHeight / 2).toFloat(),
            mPaint!!
        )
        val y = (-(mPaint!!.descent() + mPaint!!.ascent()) / 2).toInt()
        //mPaint.setColor(mTextColor);
        //canvas.drawText(str, currentProgress + mProgressPadding, mHeight / 2 + y, mPaint);
        //设置画未加载部分的颜色和宽度
        mPaint!!.color = mBackgroundColor
        mPaint!!.strokeWidth = mBackgroundHeight.toFloat()
        //清除渐变
        mPaint!!.shader = null
        //canvas.drawLine(currentProgress + textWidth + mProgressPadding * 2, mHeight / 2, getMeasuredWidth() - getPaddingRight(), mHeight / 2, mPaint);
        //画未加载部分
        canvas.drawLine(
            currentProgress,
            (mHeight / 2).toFloat(),
            currentProgress + width * (max - mProgress) / max,
            (mHeight / 2).toFloat(),
            mPaint!!
        )

        //设置文字颜色
        mPaint!!.color = mTextColor
        //是否存在文字部分
        if (showText)
            canvas.drawText(
                str,
                measuredWidth.toFloat() - paddingRight.toFloat() - textWidth,
                (mHeight / 2 + y).toFloat(),
                mPaint!!
            )
    }

    /**
     * 测量高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private fun measureHeight(heightMeasureSpec: Int): Int {
        var result: Int
        val mode = View.MeasureSpec.getMode(heightMeasureSpec)//得到测量模式
        val size = View.MeasureSpec.getSize(heightMeasureSpec)
        if (mode == View.MeasureSpec.EXACTLY) {//用户给了精确值
            result = size
        } else { //MeasureSpec.UNSPECIFIED  MeasureSpec.AT_MOST 未指定明确参数
            val textHeight = (mPaint!!.descent() - mPaint!!.ascent()).toInt()//得到文字高度
            result = paddingTop + paddingBottom + Math.max(
                mHeight,
                textHeight
            )//高度等于进度条高度和文字高度中最高的为准，并且加上padding值
            if (mode == View.MeasureSpec.AT_MOST) {//给定了最大值
                result = Math.min(result, size)
            }
        }
        return result
    }

    fun setProgress(mProgress: Int) {
        this.mProgress = mProgress
        invalidate()
    }

    fun getProgress(): Int {
        return mProgress
    }

    private fun dp2px(dp: Int): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp.toFloat(),
            resources.displayMetrics
        ).toInt()
    }

    private fun sp2px(sp: Int): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP,
            sp.toFloat(),
            resources.displayMetrics
        ).toInt()
    }

}

